<?php

/**
 * @property $_productViewsTable Core_Model_DbTable_Product_Views
 * @property $_customCategoryTable Core_Model_DbTable_Category_Customs
 */
class Core_Model_Product extends YouNet_Db_Table_Row
{
	const STATUS_DELETE = 0;
	const STATUS_SHOWN = 1;
	const STATUS_HIDDEN = 2;

	/**
	 *
	 * @var Core_Model_DbTable_Category_Customs
	 */
	private $_customCategoryTable = null;

	/**
	 *
	 * @var Core_Model_DbTable_Category_Systems
	 */
	private $_systemCategoryTable = null;
	private $_productViewsTable = null;
	private $_productSharesTable = null;
	private $_productBuysTable = null;
	private $_productImagesTable = null;
	private $_storesTable = null;

	/**
	 *
	 * @var Core_Model_Store
	 */
	private $_store;
	private $_listProductImages;

	/** @var $_currency Zend_Currency */
	private $_currency = null;

	public function init()
	{
		parent::init();
		$this->_customCategoryTable = Core_Model_DbTable_Category_Customs::getInstance();
		$this->_systemCategoryTable = Core_Model_DbTable_Category_Systems::getInstance();
		$this->_productImagesTable = new Core_Model_DbTable_Product_Images();
		$this->_productViewsTable = new Core_Model_DbTable_Product_Views();
		$this->_productSharesTable = new Core_Model_DbTable_Product_Shares();
		$this->_productBuysTable = new Core_Model_DbTable_Product_Buys();
		$this->_storesTable = Core_Model_DbTable_Stores::getInstance();
	}

	/**
	 * Get product name
	 * @return string
	 */
	public function getName()
	{
		return $this->name;
	}

	public function getCurrency()
	{
		$this->_currency = new Zend_Currency('en_US');
		$this->_currency->setFormat(
				array('display' => Zend_Currency::USE_SHORTNAME,
					'position' => Zend_Currency::RIGHT)
		);
		return $this->_currency;
	}

	/**
	 * Get product description
	 * @return string
	 */
	public function getDescription()
	{
		$quantity = 350;
		$description = strip_tags($this->description);
		$short_description = Core_Util::substr($description, 0, $quantity);
		
		if (strlen(utf8_decode($short_description)) < strlen(utf8_decode($description)))
		{
			while (true)
			{
				$last_char = substr($short_description, -1);
				if (trim($last_char) != '')
				{
					$short_description = Core_Util::substr($description, 0, $quantity++);
				}
				else
				{
					return $short_description . '...';
				}
			}
		}
		else if(strlen(utf8_decode($short_description)) > strlen(utf8_decode($description)))
		{
			return $short_description . '...';
		}
		else
		{
			return $short_description;
		}	
	}

	public function getPrice()
	{
		$unitCode = $this->getStore()->getUnitCode();
		$formatted_money = '0';
		$formatted_money = Core_Util::formatCurrency($this->price, $unitCode);
		return $formatted_money;
	}
    public function getOldPrice()
	{
		$unitCode = $this->getStore()->getUnitCode();
		$formatted_money = '0';
		$formatted_money = Core_Util::formatCurrency($this->old_price, $unitCode);
        
		return $formatted_money;
	}
	public function getProductName()
	{
		return $this->name;
	}

	/**
	 * @return Core_Model_Category_System
	 */
	public function getSystemCategory()
	{
		static $arrCategories = array();
		if( !isset($arrCategories[$this->id_system_category]) )
		{
			$arrCategories[$this->id_system_category] = $this->_systemCategoryTable->findOne($this->id_system_category);
		}
		return $arrCategories[$this->id_system_category];
	}

	/**
	 * @return Core_Model_Category_Custom
	 */
	public function getCustomCategory()
	{
		static $arrCategories = array();
		if( !isset($arrCategories[$this->id_custom_category]) )
		{
			$arrCategories[$this->id_custom_category] = $this->_customCategoryTable->findOne($this->id_custom_category);
		}
		return $arrCategories[$this->id_custom_category];
	}

	public function getCustomCategoryName()
	{
		return $this->getCustomCategory()->name;
	}

	private function getArrayPathIds()
	{
		$customCagtegory = $this->getCustomCategory();
		if (!empty($customCagtegory))
		{
			$path = $this->getCustomCategory()->path;
			if (!empty($path))
			{
				return explode(Core_Model_DbTable_Category_Abstract::DELIMITER, $path);
			}
		}
		return array();
	}

	public function getCustomBreadscrumb($path)
	{
		$arrayId = $this->getArrayPathIds();
		$rowSet = $this->_customCategoryTable->getCategoryTreeOfProduct($arrayId);

		$arrayCategories = array();

		foreach ($rowSet as $row)
		{
			$arrayCategories[htmlspecialchars($row->path . '%')] = $row->name;
		}
	
		$hasChildCategory = $this->getCustomCategory()->hasChildCategory();
		if($hasChildCategory)
		{
			$is_match = preg_match('/\-\%$/', $path);
			if($is_match == 0)
			{
				$arrayCategories[$path] = Core_Util::translate('Others');
			}
		}
		
		return $arrayCategories;
	}

	/**
	 * @return Core_Model_Store
	 */
	public function getStore()
	{
		if (empty($this->_store))
		{
			$this->_store = $this->_storesTable->findOne($this->id_store);
		}
		return $this->_store;
	}

	/**
	 *
	 * @param Core_Model_Store $store
	 * @return \Core_Model_Product
	 */
	public function setStore(Core_Model_Store $store)
	{
		$this->_store = $store;
		return $this;
	}

	/**
	 * @return Core_Mode_Product
	 */
	public function increaseViewNumber()
	{
		$session = Zend_Registry::get('session');
		if (!$session->{'view_' . $this->id})
		{
			if ($this->_doUpdateViewNumber())
			{
				$this->number_views += 1;
			}
		}
		return $this;
	}

	private function _doUpdateViewNumber()
	{
		$result = false;
		try
		{
			Zend_Db_Table::getDefaultAdapter()->beginTransaction();

			$result = ($this->_productSharesTable->insertProductInfo($this) > 0)
					&& $this->_doIncrease('views');

			Zend_Db_Table::getDefaultAdapter()->commit();
		}
		catch (Exception $ex)
		{
			Zend_Db_Table::getDefaultAdapter()->rollBack();
		}
		return $result;
	}

	/**
	 * @return Core_Mode_Product
	 */
	public function increaseShareNumber(&$id_share = null)
	{
		if ($this->_doUpdateShareNumber($id_share))
		{
			$this->number_shares += 1;
		}
		return $this;
	}

	/**
	 *
	 * @return boolean
	 */
	private function _doUpdateShareNumber(&$id_share = null)
	{
		$result = false;
		try
		{
			Zend_Db_Table::getDefaultAdapter()->beginTransaction();

			$id_share = $this->_productSharesTable->insertProductInfo($this);
			$result = ($id_share > 0 ) && $this->_doIncrease('shares');

			Zend_Db_Table::getDefaultAdapter()->commit();
		}
		catch (Exception $ex)
		{
			Zend_Db_Table::getDefaultAdapter()->rollBack();
		}
		return $result;
	}

	/**
	 * @return Core_Mode_Product
	 */
	public function increaseBuysNumber()
	{
		if ($this->_doUpdateBuysNumber())
		{
			$this->number_buys += 1;
		}
		return $this;
	}

	/**
	 *
	 * @return boolean
	 */
	private function _doUpdateBuysNumber()
	{
		$result = false;
		try
		{
			Zend_Db_Table::getDefaultAdapter()->beginTransaction();

			$result = ($this->_productBuysTable->insertProductInfo($this) > 0)
					&& $this->_doIncrease('buys');

			Zend_Db_Table::getDefaultAdapter()->commit();
		}
		catch (Exception $ex)
		{
			Zend_Db_Table::getDefaultAdapter()->rollBack();
		}
		return $result;
	}

	/**
	 * Update views/shares/buys column by one
	 * @param string $column
	 * @return int
	 */
	private function _doIncrease($column)
	{
		return $this->getTable()->update(
						array(
					$column => new Zend_Db_Expr($column . ' + 1')
						), array('id = ?' => $this->id)
		);
	}

	/**
	 *
	 * @return Zend_Db_Table_Rowset
	 */
	public function getListProductImages()
	{
		if (!$this->_listProductImages)
		{
			$key = Core_Cache_IKeys::ALL_PRODUCT_IMAGES_BY_PRODUCT . '_' . $this->id;
			$data = YouNet_Util::getObjectMemCache()->load($key);
			if ($data === false)
			{
				$this->_listProductImages = $this->findDependentRowset('Core_Model_DbTable_Product_Images');
				YouNet_Util::getObjectMemCache()->save($this->_listProductImages->toArray(), $key);
			}
			else
			{
				$rawData = array(
					'table' => $this->_productImagesTable,
					'data' => $data,
					'readOnly' => true,
					'rowClass' => $this->_productImagesTable->getRowClass(),
					'stored' => true
				);
				$rowsetClass = $this->_productImagesTable->getRowsetClass();
				$this->_listProductImages = new $rowsetClass($rawData);
			}
		}
		else
		{
			$this->_listProductImages->rewind();
		}
		return $this->_listProductImages;
	}

	/**
	 *
	 * @return array
	 */
	public function getArrIdProductImages()
	{
		$arrIdImages = array();
		foreach ($this->getListProductImages() as $imageProduct)
		{
			$arrIdImages[] = $imageProduct->id;
		}
		return $arrIdImages;
	}

	/**
	 * @return string
	 */
	public function getPrimaryImageUrl()
	{
		$imageRowset = $this->getListProductImages();
		$imageRow = $imageRowset->current();
		/* @var $imageRow Core_Model_Product_Image */
		return $imageRow->getImageUrl();
	}

	public function getPrimaryImageDescription()
	{
		$imageRowset = $this->getListProductImages();
		$imageRow = $imageRowset->current();
		/* @var $imageRow Core_Model_Product_Image */
		return $imageRow->description;
	}

	/**
	 * @return string
	 */
	public function getPrimaryThumbImageUrl()
	{
		$imageRowset = $this->getListProductImages();
		$imageRow = $imageRowset->current();
		$imageUrl = '';
		/* @var $imageRow Core_Model_Product_Image */
		if (!empty($imageRow))
		{
			$imageUrl = $imageRow->getImageThumbUrl();
		}
		return $imageUrl;
	}

	public function getShareUrl(array $params = array(), $is_app_link = true)
	{
		$params = array_merge(array(
				'module'		=> 'store',
				'controller'	=> 'share',
				'action'		=> 'product',
				'id_product'	=> $this->id
			),$params);
		$view	= Zend_Layout::getMvcInstance()->getView();
		if( !$is_app_link )
		{
			$url	= $view->serverUrl($view->url($params,'default',true));
		}
		else
		{
			$url	= $view->socialUrl($params,'default',true);
		}
		return $url;
	}

	public function getPermanentUrl()
	{
		return $this->getShareUrl(array());
	}

	public function getStatus()
	{
		switch ($this->status)
		{
			case Core_Model_DbTable_Products::STATUS_SHOWN:
				return 'PRODUCT_STATUS_SHOWN';
				break;
			case Core_Model_DbTable_Products::STATUS_HIDDEN:
				return 'PRODUCT_STATUS_HIDDEN';
				break;
			default:
				return 'PRODUCT_STATUS_UNDEFINED';
				break;
		}
	}

	public function updateFromParams(array $params)
	{
		try
		{
			$this->getTable()->getAdapter()->beginTransaction();
			foreach (array('id_system_category', 'id_custom_category') as $column)
			{
				$value = end($params[$column]);
				if (!$value)
				{
					$value = @prev($params[$column]);
				}
				if ($value)
				{
					$params[$column] = $value;
				}
			}
			if (empty($params['sku']))
			{
				$params['sku'] = new Zend_Db_Expr('NULL');
			}
			if (empty($params['price']))
			{
				$params['price'] = new Zend_Db_Expr('NULL');
			}
            else
            {
                $params['price'] = round($params['price'], 2);
            }
            if (empty($params['old_price']))
			{
				$params['old_price'] = new Zend_Db_Expr('NULL');
			}
            else
            {
                $params['old_price'] = round($params['old_price'], 2);
            }
			if( $this->getCustomCategory() )
			{
				$this->getCustomCategory()->decreaseTotalProductNumbers();
			}
			if( $this->getSystemCategory() )
			{
				$this->getSystemCategory()->decreaseTotalProductNumbers();
			}
			if ($this->status == Core_Model_DbTable_Products::STATUS_SHOWN)
			{
				if( $this->getCustomCategory() )
				{
					$this->getCustomCategory()->decreaseActiveProductNumbers();
				}
				if( $this->getSystemCategory() )
				{
					$this->getSystemCategory()->decreaseActiveProductNumbers();
				}
			}
			$this->setFromArray($params);
			$this->time_modified = time();

			$result = $this->save();

			if( $this->getCustomCategory() )
			{
				$this->getCustomCategory()->increaseTotalProductNumbers();
			}
			if( $this->getSystemCategory() )
			{
				$this->getSystemCategory()->increaseTotalProductNumbers();
			}
			if ($this->status == Core_Model_DbTable_Products::STATUS_SHOWN)
			{
				if( $this->getCustomCategory() )
				{
					$this->getCustomCategory()->increaseActiveProductNumbers();
				}
				if( $this->getSystemCategory() )
				{
					$this->getSystemCategory()->increaseActiveProductNumbers();
				}
			}
			$this->getTable()->getAdapter()->commit();
			return true;
		}
		catch (Exception $e)
		{
			$this->getTable()->getAdapter()->rollBack();
		}
		return 0;
	}

	protected function _doUpdate()
	{
		$this->invalidateCaching();
		return parent::_doUpdate();
	}

	public function invalidateCaching()
	{
		$this->getTable()->validateProductCaching($this->id, $this->id_store);
	}
	
	/**
	 * @deprecated This method SHOULD be replace by a better solution
	 * => Move validate to correct model: Core_Model_Product_Image and Core_Model_DbTable_Product_Images
	 */
	public function invalidateProductImagesCache()
	{
		$key = Core_Cache_IKeys::ALL_PRODUCT_IMAGES_BY_PRODUCT . '_' . $this->id;
		YouNet_Util::getObjectMemCache()->remove($key);
	}

	/**
	 * @deprecated by phutp. Need to consider a better solution
	 * @return Core_Model_DbTable_Products
	 */
	protected function _getTable()
	{
		if (!$this->_table)
		{
			parent::_getTable();
			if ($this->_table === NULL)
			{
				$this->_table = Core_Model_DbTable_Products::getInstance();
			}
		}
		return $this->_table;
	}

	public function getLink()
	{
		$retValue	= $this->link;
		if(!$this->linkIsUrl() )
		{
			return $retValue;
		}
		else if (strpos( $retValue, 'http', 0) === 0)
		{
			return $retValue;
		}
		return '//'.$retValue;
	}

	public function linkIsUrl()
	{
		$retValue		= $this->link;
		$arrParseValues	= explode(':',$retValue);
	
		if (count($arrParseValues) > 1)
		{
			if (strpos( $arrParseValues[0], 'http', 0) === 0)
			{
				return true;
			}
			else 
				return false;
		}
		else 
			return true;
	}

	public function getShortenerUrl(array $params = array())
	{
		$longUrl = $this->getShareUrl($params, false);
		return Core_Util::getBitlyUrl($longUrl);
	}
}